fix: MentionOnly mode retains channel context and memory capture#533
fix: MentionOnly mode retains channel context and memory capture#533
Conversation
Channel-settings-level MentionOnly was behaving identically to binding-level require_mention — suppressed messages were invisible to the agent. Now MentionOnly injects suppressed messages into the in-memory LLM context window and runs passive memory capture, so the agent stays context-aware and only skips responding. Also adds UI descriptions explaining the difference between binding-level require_mention (blocks messages entirely) and channel-level MentionOnly (agent sees everything, only responds to mentions). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (2)
WalkthroughClarifies distinction between binding-level Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/agent/channel.rs (2)
1431-1447: Suppress-path behavior is duplicated; extract to a shared helper.The MentionOnly history injection + passive memory capture flow is now duplicated in two places. Centralizing it avoids future drift between batched and single-message handling.
♻️ Suggested refactor sketch
+ async fn handle_suppressed_capture( + &mut self, + suppressed_user_texts: &[String], + message_increment: usize, + ) { + if matches!(self.resolved_settings.response_mode, ResponseMode::MentionOnly) { + let mut history = self.state.history.write().await; + for suppressed_user_text in suppressed_user_texts { + history.push(rig::message::Message::User { + content: OneOrMany::one(UserContent::text(suppressed_user_text)), + }); + } + } + self.message_count += message_increment; + self.check_memory_persistence().await; + }Also applies to: 1859-1873
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/channel.rs` around lines 1431 - 1447, Extract the duplicate "suppress-path" behavior (injecting MentionOnly entries into in-memory history and performing passive memory capture) into a shared helper and call it from both places where it currently appears; specifically, create a helper function (e.g., inject_mention_only_and_capture) that takes &mut self, an iterator over pending_batch_entries (or a single formatted_text), and message_count, performs the history.push into self.state.history.write().await for ResponseMode::MentionOnly, increments self.message_count, and calls self.check_memory_persistence().await; then replace the duplicated blocks that check for ResponseMode::MentionOnly and update message_count/check_memory_persistence with calls to this helper (references: ResponseMode::MentionOnly, pending_batch_entries, state.history, message_count, check_memory_persistence).
1444-1447: Please add targeted tests for the new MentionOnly async behavior.Given the runtime behavior change in suppression paths, add regression tests for both batched and single-message flows to verify history ingestion and passive memory capture triggering.
As per coding guidelines: “For changes in async/stateful paths (worker lifecycle, cancellation, retrigger, recall cache behavior), include explicit race/terminal-state reasoning in the PR summary and run targeted tests in addition to
just gate-pr.”Also applies to: 1870-1873
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/channel.rs` around lines 1444 - 1447, Add regression tests covering the new MentionOnly async suppression behavior: write unit/integration tests that exercise both batched and single-message flows to assert history ingestion occurs and passive memory capture is triggered (i.e., message_count increments and check_memory_persistence() is invoked) when ChannelMode::MentionOnly is used; target the async/stateful paths exercised by the code that updates self.message_count and calls check_memory_persistence(), and include assertions that ensure no suppression bypasses these calls and that behavior matches Quiet mode for passive capture. Ensure tests simulate relevant async timing/race conditions (awaits, multiple concurrent messages) and cover the other affected lines (around the similar block at 1870-1873) to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@interface/src/components/ChannelEditModal.tsx`:
- Around line 573-581: The checkbox label in ChannelEditModal (the input bound
to bindingForm.require_mention and updated via setBindingForm) is not associated
with its input for accessibility; add an explicit association by giving the
checkbox an id (e.g., requireMentionCheckbox) and reference that id from the
label's htmlFor attribute, or wrap the input element inside the label element so
clicking the text toggles the checkbox and screen readers correctly link the
label to the input.
In `@interface/src/components/ChannelSettingCard.tsx`:
- Around line 1175-1183: The checkbox label in ChannelSettingCard isn’t
associated with its input; update the JSX so the label is programmatically bound
to the input (either give the input a unique id and set the label’s htmlFor to
that id, or wrap the <input> with the <label>) for the checkbox controlling
bindingForm.require_mention; ensure the onChange and checked props remain
unchanged and that the id is unique within the component to preserve
accessibility and click-target behavior.
---
Nitpick comments:
In `@src/agent/channel.rs`:
- Around line 1431-1447: Extract the duplicate "suppress-path" behavior
(injecting MentionOnly entries into in-memory history and performing passive
memory capture) into a shared helper and call it from both places where it
currently appears; specifically, create a helper function (e.g.,
inject_mention_only_and_capture) that takes &mut self, an iterator over
pending_batch_entries (or a single formatted_text), and message_count, performs
the history.push into self.state.history.write().await for
ResponseMode::MentionOnly, increments self.message_count, and calls
self.check_memory_persistence().await; then replace the duplicated blocks that
check for ResponseMode::MentionOnly and update
message_count/check_memory_persistence with calls to this helper (references:
ResponseMode::MentionOnly, pending_batch_entries, state.history, message_count,
check_memory_persistence).
- Around line 1444-1447: Add regression tests covering the new MentionOnly async
suppression behavior: write unit/integration tests that exercise both batched
and single-message flows to assert history ingestion occurs and passive memory
capture is triggered (i.e., message_count increments and
check_memory_persistence() is invoked) when ChannelMode::MentionOnly is used;
target the async/stateful paths exercised by the code that updates
self.message_count and calls check_memory_persistence(), and include assertions
that ensure no suppression bypasses these calls and that behavior matches Quiet
mode for passive capture. Ensure tests simulate relevant async timing/race
conditions (awaits, multiple concurrent messages) and cover the other affected
lines (around the similar block at 1870-1873) to prevent regressions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0db78488-4bab-4f4a-b643-5ebc249bffae
📒 Files selected for processing (6)
interface/src/components/ChannelEditModal.tsxinterface/src/components/ChannelSettingCard.tsxinterface/src/components/ConversationSettingsPanel.tsxsrc/agent/channel.rssrc/config/types.rssrc/conversation/settings.rs
- Add compaction check after injecting suppressed messages into history in MentionOnly mode to prevent unbounded context growth (tembo) - Drop history write lock before async compaction/memory calls - Add "or given a command" to MentionOnly docs and UI description (tembo) - Wrap checkbox inputs inside label elements for accessibility (coderabbitai) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@interface/src/components/ChannelSettingCard.tsx`:
- Line 1184: Update the Mention Only helper text in ChannelSettingCard
(component ChannelSettingCard, the paragraph currently saying "Blocks messages
entirely — the agent won't see them at all. To let the agent read all messages
but only respond to mentions, use Mention Only mode in Channels settings (cog
icon).") to clarify that Mention Only still allows command invocations in
addition to mentions — e.g., change the copy to indicate the agent will only
reply to `@mentions` or slash/command invocations while still reading all
messages, so users can distinguish channel-level Mention Only from binding-level
require_mention.
In `@src/agent/channel.rs`:
- Around line 1431-1453: Avoid awaiting compaction/persistence on the
suppression fast-path: instead of awaiting
self.compactor.check_and_compact().await and
self.check_memory_persistence().await inline (inside the
ResponseMode::MentionOnly/suppression branch after pushing pending_batch_entries
and incrementing self.message_count), spawn a detached background task to run
those checks so the suppression path remains non-blocking; clone/move the
minimal pieces needed into the task (e.g., Arc::clone(&self) or
self.compactor.clone()) and call compactor.check_and_compact().await and
self.check_memory_persistence().await inside tokio::spawn (or equivalent) so
errors can be logged but do not block the channel.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cd90689e-bcab-498b-8897-5a876cd30ff6
📒 Files selected for processing (5)
interface/src/components/ChannelEditModal.tsxinterface/src/components/ChannelSettingCard.tsxinterface/src/components/ConversationSettingsPanel.tsxsrc/agent/channel.rssrc/conversation/settings.rs
✅ Files skipped from review due to trivial changes (2)
- src/conversation/settings.rs
- interface/src/components/ChannelEditModal.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- interface/src/components/ConversationSettingsPanel.tsx
The binding-level helper text now mentions commands, mentions, and replies — matching the actual MentionOnly trigger behavior. The compaction await is kept inline: check_and_compact() is cheap (read lock + token estimate) and spawns workers for real compaction, consistent with existing non-suppression call sites. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
require_mention— suppressed messages were invisible to the agent on its next turnTest plan
🤖 Generated with Claude Code
Note
AI-generated summary: This fix changes how MentionOnly mode works at the channel level. Instead of completely suppressing unmentioned messages from the agent (like binding-level
require_mentiondoes), MentionOnly now keeps them in the agent's context window while preventing automatic responses. The agent sees the conversation flow and memory accumulates passively, creating a more aware but selectively-responsive bot. UI improvements clarify the distinction between these two levels of mention enforcement.Written by Tembo for commit 99467d2. This will update automatically on new commits.